from __future__ import annotations

from dataclasses import dataclass
from math import cosh, sinh


@dataclass
class CatenaryState:
    horizontal_tension_kN: float
    sag_m: float
    note: str


def catenary_by_midspan(span_m: float, unit_weight_kN_m: float, midspan_sag_m: float) -> CatenaryState:
    """精确悬链线：给定跨距与跨中弧垂，求水平张力 H = w·a，a 由 f = a(cosh(l/(2a)) - 1) 反解。
    用牛顿迭代求 a。"""

    w = unit_weight_kN_m
    l = span_m
    f = midspan_sag_m
    a = max(0.01, (w * l * l) / (8.0 * max(1e-6, f)))  # 初值来自抛物线
    for _ in range(30):
        F = a * (cosh(l / (2.0 * a)) - 1.0) - f
        dF = cosh(l / (2.0 * a)) * (-l / (2.0 * a)) + (cosh(l / (2.0 * a)) - 1.0)
        da = -F / max(1e-9, dF)
        a += da
        if abs(da) < 1e-8:
            break
    H = w * a
    return CatenaryState(horizontal_tension_kN=H, sag_m=f, note="悬链线精解")


